import clsx from 'clsx';
import dayjs from 'dayjs';
import React, { useImperativeHandle, useRef } from 'react';
import { FolderFilled, FolderOpenFilled } from '@ant-design/icons';
import { PencilSquareIcon, XMarkIcon } from '@heroicons/react/24/outline';
import { getFolderInfoById } from 'src/actions/folder';
import { Tabs } from 'src/components/Tabs';
import { ExplorerItem } from 'src/hooks/useExplorerInfiniteScroll';
import { Shortcuts } from './Shortcuts';
import { ImageView } from 'src/components/ImageView';
import { PhotoProvider, PhotoView } from 'react-photo-view';

type FolderInfo = Awaited<ReturnType<typeof getFolderInfoById>>;

export interface AsideRef {
  /**
   * 触发预览照片的操作
   */
  previewPhotos: () => void;
}

export interface AsideProps {
  ref?: React.Ref<AsideRef>;
  title: string;
  selectedRows?: ExplorerItem[];
  visible?: boolean;
  folderInfo?: FolderInfo;
  onClose?: () => void;
}

function AsideNoMemoized(props: AsideProps) {
  const { ref, title, selectedRows, folderInfo, visible, onClose } = props;

  // Refs
  const imageTriggerRef = useRef<HTMLImageElement>(null);

  const noSelected = !selectedRows?.length;
  const oneSelected = selectedRows?.length === 1;
  const multipleSelected = Array.isArray(selectedRows) && selectedRows.length > 1;

  useImperativeHandle(
    ref,
    () => ({
      previewPhotos: () => {
        if (imageTriggerRef.current) {
          imageTriggerRef.current.click();
        }
      },
    }),
    []
  );

  let core = null;

  if (noSelected) {
    // 未选中任何行
    core = (
      <div className="flex h-full flex-col items-center justify-center p-2.5">
        <div className="flex-none h-[230px] flex flex-col items-center justify-center gap-5">
          <div className="bg-[url('/images/no_select_data.webp')] bg-contain bg-center w-full h-[180px] dark:brightness-50" />
          <span className="text-xs text-gray-500 dark:text-gray-400">
            未选中任何文件（夹），请勾选框后查看
          </span>
        </div>
        <Shortcuts className="mt-10 flex-none" />
      </div>
    );
    if (folderInfo) {
      core = (
        <div className="flex-1 flex flex-col">
          <div className="w-full h-16 text-yellow-600 bg-gray-50 dark:bg-neutral-950 border-b border-gray-200 dark:border-neutral-700 flex items-center justify-center">
            <FolderOpenFilled className="text-3xl" />
          </div>
          <div className="flex flex-col gap-2 p-2.5">
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                文件夹名称：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">{folderInfo.name}</span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">描述：</span>
              <span className="text-gray-800 dark:text-neutral-200">
                {folderInfo.description || '-'}
              </span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                创建日期：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">
                {dayjs(folderInfo.createdAt).format('YYYY-MM-DD HH:mm:ss') || '-'}
              </span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                图片数量：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">{folderInfo.imageCount}</span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                图片大小：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">
                {(folderInfo.totalFileSize / 1024 / 1024).toFixed(2)}M
              </span>
            </div>
          </div>
        </div>
      );
    }
  } else if (oneSelected) {
    // 选中单行
    const item = selectedRows[0];
    if (item.type === 'image') {
      core = (
        <div className="w-full flex flex-col items-center">
          <PhotoProvider>
            <PhotoView src={item.imageUrl}>
              <ImageView
                ref={imageTriggerRef}
                key={item.id}
                alt={item.name}
                src={item.imageUrl}
                width={318}
                height={160}
                className={clsx(
                  'border-b border-gray-200 dark:border-neutral-700 bg-asset-grid cursor-pointer',
                  'object-cover hover:object-contain'
                )}
              />
            </PhotoView>
          </PhotoProvider>
          <Tabs
            className="justify-center mt-1"
            contentClassName="rounded-none border-l-0 border-r-0"
            type="border"
            destroyOnHidden
            items={[
              {
                label: '图片属性',
                key: 'image-attribute',
                children: (
                  <div className="flex flex-col gap-1">
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        文件名：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">{item.name}</span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        图片描述：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.description || '-'}
                      </span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        图片大小：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.fileSize || '-'}字节
                      </span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        标签：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.tags?.length ? item.tags.map((tag) => tag.label).join(', ') : '-'}
                      </span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        创建时间：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.createdAt || '-'}
                      </span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        访问权限：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.isPublic ? '公开' : '私有'}
                      </span>
                    </div>
                    <div className="flex text-xs">
                      <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                        存储实例：
                      </span>
                      <span className="text-gray-800 dark:text-neutral-200">
                        {item.storageSystem}
                      </span>
                    </div>
                  </div>
                ),
              },
              {
                label: '元数据',
                key: 'image-metadata',
                children: (
                  <div className="flex flex-col gap-1">
                    {Object.entries(item.metadata.origin ?? {}).map(([key, value]) => (
                      <div key={key} className="flex text-xs">
                        <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                          {`${key}：`}
                        </span>
                        <span className="text-gray-800 dark:text-neutral-200">
                          {value?.toString() ?? '-'}
                        </span>
                      </div>
                    ))}
                  </div>
                ),
              },
            ]}
          />
        </div>
      );
    }
    if (item.type === 'folder') {
      core = (
        <div className="flex flex-col">
          <div className="w-full h-16 text-yellow-600 bg-gray-50 dark:bg-neutral-950 border-b border-gray-200 dark:border-neutral-700 flex items-center justify-center">
            <FolderFilled className="text-3xl" />
          </div>
          <div className="flex flex-col gap-1 p-2.5">
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                文件夹名称：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">{item.name}</span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">描述：</span>
              <span className="text-gray-800 dark:text-neutral-200">{item.description || '-'}</span>
            </div>
            <div className="flex text-xs">
              <span className="text-gray-500 dark:text-neutral-400 flex-none w-[90px]">
                创建时间：
              </span>
              <span className="text-gray-800 dark:text-neutral-200">{item.createdAt || '-'}</span>
            </div>
          </div>
        </div>
      );
    }
  } else if (multipleSelected) {
    // 选中多行
    core = (
      <div className="w-full flex flex-col gap-5">
        <div aria-label="selected-images" className="stack w-full">
          <PhotoProvider>
            {selectedRows.toReversed().map((item, index) => {
              if (item.type === 'image') {
                // 只显示第一张图片的预览，其他显示占位符，防止大量图片加载导致性能问题
                return (
                  <PhotoView key={item.id} src={item.imageUrl}>
                    {index === 0 ? (
                      <ImageView
                        ref={imageTriggerRef}
                        alt={item.name}
                        src={`${item.imageUrl}?w=318&h=160&format=webp`}
                        width={318}
                        height={160}
                        className="object-cover border-b border-gray-300 dark:border-neutral-700 cursor-pointer"
                      />
                    ) : (
                      <div className="w-[318px] h-[160px] bg-slate-700 border border-slate-200 dark:border-slate-400" />
                    )}
                  </PhotoView>
                );
              }
              return null;
            })}
          </PhotoProvider>
        </div>
        <Shortcuts className="mt-5 flex-none" />
      </div>
    );
  }

  if (visible) {
    return (
      <aside
        aria-label="properties"
        className="flex-none w-80 flex flex-col border border-gray-200 dark:border-neutral-700"
      >
        <div className="flex-none flex items-center h-[47px] px-2.5 text-sm overflow-hidden border-b border-gray-200 dark:border-neutral-700">
          <strong
            className="flex-auto w-full text-gray-600 dark:text-neutral-400 truncate"
            title={title}
          >
            {title}
          </strong>
          <div className="flex-none flex items-center gap-2">
            {oneSelected && (
              <button type="button" className="btn btn-sm btn-ghost btn-circle" title="编辑">
                <PencilSquareIcon className="size-4" />
              </button>
            )}
            <button
              type="button"
              className="btn btn-sm btn-ghost btn-circle"
              title="关闭"
              onClick={onClose}
            >
              <XMarkIcon className="size-4" />
            </button>
          </div>
        </div>
        <div className="flex-auto overflow-y-auto overflow-x-hidden">{core}</div>
      </aside>
    );
  }

  return null;
}

export const Aside = React.memo(AsideNoMemoized);
